package cn.pink.common.support.tools.rpc;

import cn.hutool.core.util.RandomUtil;
import cn.pink.core.config.IronConfig;
import cn.pink.core.support.function.IronFunction1;
import cn.pink.rpc.db.DBGrpc;
import cn.pink.rpc.db.FindHumanReply;
import cn.pink.rpc.db.FindHumanRequest;
import io.vertx.core.Future;
import io.vertx.core.Vertx;
import io.vertx.core.net.SocketAddress;
import io.vertx.grpc.client.GrpcClient;
import io.vertx.grpc.client.GrpcClientRequest;

import java.util.ArrayList;
import java.util.List;

/**
 * @Author: pink
 * @Date: 2022/7/13 17:51
 */
public class RpcTool {
    private static RpcTool tool = new RpcTool();

    private RpcTool() {

    }

    public static RpcTool getInstance() {
        return tool;
    }

    private Vertx vertx;

    private GrpcClient client;
    private List<SocketAddress> address = new ArrayList<>();

    public void init(Vertx vertx) {
        this.vertx = vertx;

        client = GrpcClient.client(vertx);

        List<String> hosts = List.of(IronConfig.DB_RPC_HOST.split(","));

        hosts.forEach(host -> {
            address.add(SocketAddress.inetSocketAddress(IronConfig.DB_RPC_PORT, host));
        });
    }

    /**
     * 随机一个rpc服务地址
     */
    private SocketAddress getRpcAddress() {
        return RandomUtil.randomEle(address);
    }

    //---------------------------------- rpc method ----------------------------------

    /**
     * 查找human
     */
    public void findHuman(String id, IronFunction1<String> function1) {
        Future<GrpcClientRequest<FindHumanRequest, FindHumanReply>> fut = client.request(getRpcAddress(), DBGrpc.getFindHumanMethod());

        fut.onSuccess(request -> {
            request.end(FindHumanRequest.newBuilder().setId(id).build());

            request.response().onSuccess(resp -> {
                Future<FindHumanReply> re = resp.last();
                re.onSuccess(reply -> function1.apply("Received " + reply.getMessage()));
            });
        });
    }
}
